import * as cc from "cc";
import yyComponent from "../Common/yyComponent";
import { EventType } from "../GameSpecial/GameEventType";
import GlobalPool from "../Common/GlobalPool";
import RecommendDataManager from "./RecommendDataManager";
import RecommendContainer from "./RecommendContainer";
import { GlobalEnum } from "../GameSpecial/GlobalEnum";
import Loader from "../Common/Loader";
import { AdConfig } from "../GameSpecial/AdConfig";
import http_request from "../Common/http_request";
import GlobalData from "../Common/GlobalData";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Recommend extends yyComponent {
    /**显示互推的场景/UI，使用堆栈来管理 */
    protected sceneStack;
    /**是否已作出计划要根据场景更新互推内容 */
    protected scheduledRecommend: boolean;

    public init() {
        this.scheduledRecommend = false;
        this.initSceneStack();
        this.loadCommonPrefab();
        this.onEvents();
    }
    protected onEvents() {
        this.once(EventType.Common.RecommendEvent.assetLoadFinish, this.onConfigLoadFinish, this);

        this.on(EventType.Common.RecommendEvent.clickRecommendItem, this.onClickRecommendItem, this);
        this.on(EventType.Common.RecommendEvent.autoNavigate, this.navigateGame, this);

        this.on(EventType.Common.RecommendEvent.showRecommend, this.addRecommend, this);
        this.on(EventType.Common.RecommendEvent.showBigPage, this.showBigPage, this);
        this.on(EventType.Common.RecommendEvent.showMiddlePage, this.showMiddlePage, this);
        this.on(EventType.Common.RecommendEvent.showLittlePage, this.showLittlePage, this);
        this.on(EventType.Common.RecommendEvent.showRecommendDialog, this.showRecommendDialog, this);
        this.on(EventType.Common.RecommendEvent.showInsteadBannerRecommend, this.showInsteadBannerRecommend, this);
        this.on(EventType.Common.RecommendEvent.showSingleRecommend, this.showSingleRecommend, this);
        this.on(EventType.Common.RecommendEvent.hideSingleRecommend, this.hideSingleRecommend, this);

        this.on(EventType.Common.SDKEvent.hideBanner, this.hideInsteadBannerRecommend, this);

        this.on(EventType.Common.UIEvent.entered, this.onEnterScene, this);
        this.on(EventType.Common.UIEvent.exited, this.onExitScene, this);

    }
    protected initSceneStack() {
        this.sceneStack = [];
    }
    /**回收所有主推游戏节点 */
    public reset() {
        this.scheduledRecommend = false;
        this.resetSceneStack();
        GlobalPool.putAllChildren(this.node);
    }
    protected resetSceneStack() {
        this.sceneStack = [];
    }


    /**进入需要显示互推的场景/UI */
    protected onEnterScene(scene) {
        this.hideInsteadBannerRecommend();
        if (undefined === scene || null === scene) return;
        //未对该场景进行互推配置时，不对其进行记录
        let config = RecommendDataManager.getConfig(scene);
        if (undefined === config) return;
        let curScene = this.getCurScene();
        if (curScene == scene) return;
        for (let i = this.sceneStack.length - 1; i >= 0; --i) {
            if (this.sceneStack[i] == scene) {
                this.sceneStack.splice(i, 1);
                break;
            }
        }
        this.sceneStack.push(scene);
        this.updateRecommends();
    }
    /**获取当前显示在最上层的互推场景/UI */
    protected getCurScene() {
        let count = this.sceneStack.length;
        if (count == 0) return null;
        return this.sceneStack[count - 1];
    }
    /**退出需要显示互推的场景/UI */
    protected onExitScene(scene) {
        if (undefined === scene || null === scene) return;
        this.hideInsteadBannerRecommend();
        //未对该场景进行互推配置时，不需要进行处理
        let config = RecommendDataManager.getConfig(scene);
        if (undefined === config) return;
        let curScene = this.getCurScene();
        if (curScene == scene) {
            this.sceneStack.pop();
            this.updateRecommends();
        } else {
            for (let i = this.sceneStack.length - 1; i >= 0; --i) {
                if (this.sceneStack[i] == scene) {
                    this.sceneStack.splice(i, 1);
                    break;
                }
            }
        }
    }

    /**互推配置表加载完毕，延迟更新互推内容 */
    protected onConfigLoadFinish() {
        this.updateRecommends();
    }

    /**切换UI/场景，显示对应的互推内容 */
    protected updateRecommends() {
        //使用计时器，到下一帧才更新互推内容，
        //避免游戏中执行初始化、重置等流程时场景/UI切换过多，
        //需要在一帧中反复显隐互推内容
        if (this.scheduledRecommend) return;
        setTimeout(this.showCurSceneRecommend.bind(this), 50);
        this.scheduledRecommend = true;
    }
    /**根据显示在最上层的场景/UI，显示相应的互推内容 */
    protected showCurSceneRecommend() {
        this.scheduledRecommend = false;
        GlobalPool.putAllChildren(this.node);
        let config;
        for (let i = this.sceneStack.length - 1; i >= 0; --i) {
            config = RecommendDataManager.getConfig(this.sceneStack[i]);
            if (undefined === config) {
                this.sceneStack.splice(i, 1);
            } else {
                break;
            }
        }
        if (!config) return;
        for (let i = config.length - 1; i >= 0; --i) {
            this.addRecommend(config[i]);
        }
    }
    protected addRecommend(config) {
        let count = config.count || 0;
        let data = RecommendDataManager.getRecommendData(config.AdID, count);
        if (!!data && data.length == 0) {
            return;
        }
        let node = GlobalPool.get(config.name, {
            itemType: config.itemType,
            widget: config.widget,
            items: data,
            nodeWidgets: config.nodeWidgets,
            count: count,
        });
        this.node.addChild(node);
        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData(config.AdID, (items) => {
                if (items.length == 0) {
                    GlobalPool.put(node);
                } else {
                    node.getComponent(RecommendContainer).setRecommendData(items);
                }
                this.recordRecommond(items);
            }, count);
        } else {
            this.recordRecommond(data);
        }
    }

    //记录曝光次数 
    protected recordRecommond(data) {
        let str = '';
        for (let i = data.length - 1; i >= 0; --i) {
            str += data[i].id + ",";
        }
        str = str.substr(0, str.length - 2);
        http_request.postRequest('https://ad.geyian.ink/v1.1/api/adshow.html', { id: str }, () => {
            console.log("recordRecommond: " + str + ' 上报曝光成功');
        })

    }

    protected commonPrefabLoaded: boolean = false;
    protected loadCommonPrefab(cb?) {
        if (!!this.commonPrefabLoaded) {
            !!cb && cb();
            return;
        }
        Loader.loadBundle("Recommend", () => {
            Loader.loadBundleDir("Recommend", "Prefab", (assets) => {
                for (let i = 0; i < assets.length; ++i) {
                    GlobalPool.createPool(assets[i].name, assets[i], assets[i].name);
                }
                this.commonPrefabLoaded = true;
                if (!!cb) {
                    cb();
                }
            }, cc.Prefab, false);
        }, true, false);
    }

    /**将导流页显示到最上面 */
    protected setNodeTop(node: cc.Node) {
        let s1 = 0;
        s1 = this.getMaxSibling(this.node, s1);
        s1 = this.getMaxSibling(this.bigPage, s1);
        s1 = this.getMaxSibling(this.middlePage, s1);
        s1 = this.getMaxSibling(this.littlePage, s1);
        s1 = this.getMaxSibling(this.recommendDialog, s1);
        s1 = this.getMaxSibling(this.insteadBannerRecommend, s1);
        node.setSiblingIndex(s1);
    }
    protected getMaxSibling(node: cc.Node, sibling) {
        if (!node) return sibling;
        let s = node.getSiblingIndex();
        return s < sibling ? sibling : s;
    }

    //#region 小全导页
    protected littlePage: cc.Node = null;
    protected littlePageConfig: any;
    protected showLittlePage(data: { data?: any, config?: any } = {}) {
        this.littlePageConfig = data;
        //已经显示时，随机刷新列表
        if (!!this.littlePage && this.littlePage.activeInHierarchy) {
            // this.littlePage.getComponent(RecommendContainer).refreshRecommendData();
            this.setNodeTop(this.littlePage);
            return;
        }

        if (!this.littlePage) {
            this.loadCommonPrefab(() => {
                Loader.loadBundleRes("Recommend", "SinglePrefab/Recommend_littlePage", (res) => {
                    this.littlePage = cc.instantiate(res);
                    this.littlePage.getComponent(RecommendContainer).init();
                    this.node.parent.addChild(this.littlePage);
                    this.littlePage.setSiblingIndex(this.node.getSiblingIndex() + 1);
                    this.showRecommendLittlePageData();
                }, cc.Prefab, true);
            });
        } else {
            this.showRecommendLittlePageData();
        }
    }
    protected showRecommendLittlePageData() {
        let count = this.littlePage.getComponent(RecommendContainer).count;
        let data = RecommendDataManager.getRecommendData("littleView", count);
        this.littlePage.getComponent(RecommendContainer).show({
            items: data,
            data: this.littlePageConfig.data,
            config: this.littlePageConfig.config,
        });
        this.setNodeTop(this.littlePage);
        this.emit(EventType.Common.UIEvent.entered, GlobalEnum.UI.littlePage);

        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData("littleView", (items) => {
                this.littlePage.getComponent(RecommendContainer).setRecommendData(items);
                this.recordRecommond(items);
            }, count);
        } else {
            this.recordRecommond(data);
        }
    }
    protected hideLittlePage() {
        if (!!this.littlePage) {
            this.littlePage.getComponent(RecommendContainer).reset();
            this.littlePage.active = false;
        }
        this.emit(EventType.Common.UIEvent.exited, GlobalEnum.UI.littlePage);
    }
    //#endregion

    //#region 中全导页
    protected middlePage: cc.Node = null;
    protected middlePageConfig: any;
    protected showMiddlePage(data: { data?: any, config?: any } = {}) {
        this.middlePageConfig = data;
        //已经显示时，随机刷新列表
        if (!!this.middlePage && this.middlePage.activeInHierarchy) {
            this.middlePage.getComponent(RecommendContainer).refreshRecommendData();
            this.setNodeTop(this.middlePage);
            return;
        }

        if (!this.middlePage) {
            this.loadCommonPrefab(() => {
                Loader.loadBundleRes("Recommend", "SinglePrefab/Recommend_middlePage", (res) => {
                    this.middlePage = cc.instantiate(res);
                    this.middlePage.getComponent(RecommendContainer).init();
                    this.node.parent.addChild(this.middlePage);
                    this.middlePage.setSiblingIndex(this.node.getSiblingIndex() + 1);
                    this.showRecommendMiddlePageData();
                }, cc.Prefab, true);
            });
        } else {
            this.showRecommendMiddlePageData();
        }
    }
    protected showRecommendMiddlePageData() {
        let count = this.middlePage.getComponent(RecommendContainer).count;
        let data = RecommendDataManager.getRecommendData("middleView", count);
        this.middlePage.getComponent(RecommendContainer).show({
            items: data,
            data: this.middlePageConfig.data,
            config: this.middlePageConfig.config,
        });
        this.setNodeTop(this.middlePage);
        this.emit(EventType.Common.UIEvent.entered, GlobalEnum.UI.middlePage);

        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData("middleView", (items) => {
                this.middlePage.getComponent(RecommendContainer).setRecommendData(items);
                this.recordRecommond(items);
            }, count);
        } else {
            this.recordRecommond(data);
        }
    }
    protected hideMiddlePage() {
        if (!!this.middlePage) {
            this.middlePage.getComponent(RecommendContainer).reset();
            this.middlePage.active = false;
        }
        this.emit(EventType.Common.UIEvent.exited, GlobalEnum.UI.middlePage);
    }
    //#endregion

    //#region 大全导页
    protected bigPage: cc.Node = null;
    protected bigPageConfig: any;
    protected showBigPage(data: { data?: any, config?: any } = {}) {
        if (undefined !== data) {
            this.bigPageConfig = data;
        }
        //已经显示时，随机刷新列表
        if (!!this.bigPage && this.bigPage.activeInHierarchy) {
            this.bigPage.getComponent(RecommendContainer).refreshRecommendData();
            this.setNodeTop(this.bigPage);
            return;
        }

        if (!this.bigPage) {
            this.loadCommonPrefab(() => {
                Loader.loadBundleRes("Recommend", "SinglePrefab/Recommend_bigPage", (res) => {
                    this.bigPage = cc.instantiate(res);
                    this.bigPage.getComponent(RecommendContainer).init();
                    this.node.parent.addChild(this.bigPage);
                    this.bigPage.setSiblingIndex(this.node.getSiblingIndex() + 1);
                    this.showRecommendBigPageData();
                }, cc.Prefab, true);
            });
        } else {
            this.showRecommendBigPageData();
        }
    }
    protected showRecommendBigPageData() {
        let count = this.bigPage.getComponent(RecommendContainer).count;
        let data = RecommendDataManager.getRecommendData("bigView", count);
        this.bigPage.getComponent(RecommendContainer).show({
            items: data,
            data: this.bigPageConfig.data,
            config: this.bigPageConfig.config,
        });
        this.setNodeTop(this.bigPage);
        this.emit(EventType.Common.UIEvent.entered, GlobalEnum.UI.bigPage);

        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData("bigView", (items) => {
                this.bigPage.getComponent(RecommendContainer).setRecommendData(items);
                this.recordRecommond(items);
            }, count);
        } else {
            this.recordRecommond(data);
        }
    }
    protected hideBigPage() {
        if (!!this.bigPage) {
            this.bigPage.getComponent(RecommendContainer).reset();
            this.bigPage.active = false;
        }
        this.emit(EventType.Common.UIEvent.exited, GlobalEnum.UI.bigPage);
    }

    //#endregion

    //#region 进入首页弹窗
    protected recommendDialog = null;
    protected recommendDialogConfig: any;
    protected showRecommendDialog(data: { data?: any, config?: any } = {}) {
        this.recommendDialogConfig = data;
        if (!!this.recommendDialog && this.recommendDialog.activeInHierarchy) {
            this.recommendDialog.getComponent(RecommendContainer).refreshRecommendData();
            this.setNodeTop(this.recommendDialog);
            return;
        }
        if (!this.recommendDialog) {
            this.loadCommonPrefab(() => {
                Loader.loadBundleRes("Recommend", "SinglePrefab/RecommendDialog", (res) => {
                    this.recommendDialog = cc.instantiate(res);
                    this.recommendDialog.getComponent(RecommendContainer).init();
                    this.node.parent.addChild(this.recommendDialog);
                    this.recommendDialog.setSiblingIndex(this.node.getSiblingIndex() + 1);
                    this.showRecommendDialogData();
                }, cc.Prefab, true);
            });
        } else {
            this.showRecommendDialogData();
        }
    }
    protected showRecommendDialogData() {
        let count = this.recommendDialog.getComponent(RecommendContainer).count;
        let data = RecommendDataManager.getRecommendData("dialog", count);
        this.recommendDialog.getComponent(RecommendContainer).show({
            items: data,
            data: this.recommendDialogConfig.data,
            config: this.recommendDialogConfig.config,
        });
        this.setNodeTop(this.recommendDialog);
        this.emit(EventType.Common.UIEvent.entered, GlobalEnum.UI.recommendDialog);

        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData("dialog", (items) => {
                this.recommendDialog.getComponent(RecommendContainer).setRecommendData(items);
                this.recordRecommond(items);
            }, count);
        } else {
            this.recordRecommond(data);
        }
    }
    protected hideRecommendDialog() {
        if (!!this.recommendDialog) {
            this.recommendDialog.getComponent(RecommendContainer).reset();
            this.recommendDialog.active = false;
        }
        this.emit(EventType.Common.UIEvent.exited, GlobalEnum.UI.recommendDialog);
    }
    //#endregion

    //#region 代替banner的广告位
    protected insteadBannerRecommend: cc.Node = null;
    protected showInsteadBannerRecommend(config) {
        let count = config.count || 0;
        if (!!this.insteadBannerRecommend) {
            this.insteadBannerRecommend.active = true;
            this.setNodeTop(this.insteadBannerRecommend);
            this.insteadBannerRecommend.getComponent(RecommendContainer).setWidgetConfig({ widget: config.widget });
            this.insteadBannerRecommend.getComponent(RecommendContainer).refreshRecommendData();
            return;
        }
        let data = RecommendDataManager.getRecommendData(config.AdID, count);
        let node = GlobalPool.get(config.name, {
            itemType: config.itemType,
            widget: config.widget,
            items: data,
            nodeWidgets: config.nodeWidgets,
            count: count,
        });
        this.insteadBannerRecommend = node;
        this.node.parent.addChild(node);
        this.insteadBannerRecommend.setSiblingIndex(this.node.getSiblingIndex() + 1);
        this.setNodeTop(this.insteadBannerRecommend);
        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData(config.AdID, (items) => {
                node.getComponent(RecommendContainer).setRecommendData(items);
                this.recordRecommond(items);
            }, count);
        } else {
            this.recordRecommond(data);
        }
    }
    protected hideInsteadBannerRecommend() {
        if (!!this.insteadBannerRecommend) {
            GlobalPool.put(this.insteadBannerRecommend);
            this.insteadBannerRecommend = null;
        }
    }
    //#endregion

    //#region 样式同banner的单个游戏的广告位
    protected singleRecommend: cc.Node = null;
    protected singleID: string;
    protected showSingleRecommend(adID?: string | number) {
        if (!adID) {
            this.singleID = "singleBanner";
        } else {
            if (typeof adID === "number") {
                for (let key in AdConfig.AdID) {
                    if (AdConfig.AdID[key] === adID) {
                        this.singleID = key;
                        break;
                    }
                }
            } else {
                this.singleID = adID;
            }
        }
        this.emit(EventType.Common.SDKEvent.hideBanner);
        if (!this.singleRecommend) {
            this.singleRecommend = new cc.Node();
            let cvs = this.node.parent;
            let transform = this.singleRecommend.getComponent(cc.UITransform);
            transform.width = GlobalData.get(GlobalEnum.Common.GlobalDataType.canvasTransform).width;
            transform.height = GlobalData.get(GlobalEnum.Common.GlobalDataType.canvasTransform).height;
            cvs.addChild(this.singleRecommend);
            this.singleRecommend.setPosition(0, 0);
        }
        this.singleRecommend.active = true;
        if (this.singleRecommend.children.length > 0) return;
        let data = RecommendDataManager.getRecommendData(this.singleID);
        if (!data || data.length == 0) {
            RecommendDataManager.loadAdData(this.singleID, this.addSingleRecommend.bind(this));
        } else {
            this.addSingleRecommend(data);
        }
    }
    protected addSingleRecommend(data) {
        if (!data || data.length == 0) return;
        if (!this.singleRecommend.active || this.singleRecommend.children.length > 0) return;

        let index = Math.floor(Math.random() * (data.length - 0.0001));
        let node = GlobalPool.get("RecommendItemIcon_common", data[index]);
        if (!node) {
            return;
        }
        this.singleRecommend.addChild(node);
        let transf = node.getComponent(cc.UITransform);
        transf.setContentSize(750, 260);
        let y = -0.5 * this.singleRecommend.getComponent(cc.UITransform).height + transf.height * transf.anchorY;
        node.setPosition(cc.v3(0, y, 0));
    }
    protected hideSingleRecommend() {
        if (!this.singleRecommend) return;
        GlobalPool.putAllChildren(this.singleRecommend);
        this.singleRecommend.active = false;
    }
    //#endregion

    /**玩家主动点击互推游戏节点，跳转游戏 */
    protected onClickRecommendItem(data) {
        //广告位已跳转过时，随机选择一个其他未进行跳转的游戏进行跳转
        let jumpCount = RecommendDataManager.getJumpRecommend(data.appid);
        if (jumpCount > 0) {
            let d = RecommendDataManager.getUnjumpData(data.locationid);
            if (!!d) {
                data = d;
            }
        }
        this.emit(EventType.Common.SDKEvent.navigateToMiniProgram, data, this.onNavigateComplate);
    }
    /**跳转请求回调 */
    protected onNavigateComplate(isNavigated: boolean, data) {
        if (isNavigated) {
            this.onNavigateSuccess(data);
        } else {
            this.onNavigateFail(data);
        }
    }
    //跳转成功，记录跳转次数
    protected onNavigateSuccess(data) {
        //记录跳转次数
        RecommendDataManager.recordJumpGame(data);
    }
    //取消跳转后的刷新行为
    protected onNavigateFail(data) {
    }
    //刷新全导页
    protected refreshRecommendUI(data) {
        let id = parseInt(data.locationid);
        switch (id) {
            case AdConfig.AdID.bigView: {
                this.refreshRecommendData(this.bigPage);
                break;
            }
            case AdConfig.AdID.middleView: {
                this.refreshRecommendData(this.middlePage);
                break;
            }
            case AdConfig.AdID.littleView: {
                this.refreshRecommendData(this.littlePage);
                break;
            }
            case AdConfig.AdID.dialog: {
                this.refreshRecommendData(this.recommendDialog);
                break;
            }
        }
    }
    //刷新全导页内容
    protected refreshRecommendData(node: cc.Node) {
        if (!!node && node.activeInHierarchy) {
            node.getComponent(RecommendContainer).refreshRecommendData();
        }
    }
    /**代码调用跳转到其他小游戏 */
    protected navigateGame(data: any) {
        this.emit(EventType.Common.SDKEvent.navigateToMiniProgram, data);
    }
}
